home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Multimedia Viewer How-To CD / Microsoft Multimedia Viewer How-To CD.iso / mvsample / progsamp / katasrch / katasrch.c < prev    next >
C/C++ Source or Header  |  1993-03-21  |  26KB  |  940 lines

  1. #include <windows.h>
  2. #include <viewer.h>
  3. #include <stdlib.h>
  4.  
  5. #include "katasrch.h"
  6. #include "mvbtask.h"
  7. #include "results.h"
  8.  
  9. HANDLE ghModule = NULL;
  10. PSTR szTitleSearch = "Search";
  11. PSTR szTitleResults = "Topics Found";
  12.  
  13.  
  14. /************************************************************************
  15.  * LibMain: Initialization function for the DLL
  16.  *
  17.  * - Initialize Results list, which keeps track of Topics Found windows
  18.  * - Store DLL module handle in global variable
  19.  * - Register Results window class
  20.  *
  21.  ************************************************************************/
  22.  
  23. int CALLBACK LibMain(
  24.     HINSTANCE hinst,                // handle of library instance
  25.     WORD wDataSeg,                  // library data segment
  26.     WORD cbHeap,                    // default heap size
  27.     LPSTR lpszCmdLine )             // command-line arguments
  28. {
  29.     // Save the module handle
  30.  
  31.     ghModule = hinst;
  32.  
  33.     if(cbHeap)
  34.         UnlockData(0);
  35.  
  36.     // Initialize the tasks list
  37.  
  38.     InitTasks();
  39.  
  40.     return 1;
  41. }
  42.  
  43. /**************************************************************************
  44.  * GetDialogFont
  45.  *
  46.  * Creates the font used in search dialog box and results window.
  47.  **************************************************************************/
  48.  
  49. HFONT GetDialogFont(HWND hwnd)
  50. {
  51.     HDC hdc = GetDC(hwnd);
  52.     HFONT hfont;
  53.     PLOGFONT plf = (PLOGFONT)LocalAlloc(LPTR, sizeof(LOGFONT));
  54.  
  55.     plf->lfWeight = FW_BOLD;
  56.     plf->lfHeight = -MulDiv(8, GetDeviceCaps(hdc, LOGPIXELSY), 72);
  57.     lstrcpy(plf->lfFaceName, "MS Sans Serif");
  58.  
  59.     hfont = CreateFontIndirect(plf);
  60.  
  61.     LocalFree((HLOCAL) plf);
  62.     ReleaseDC(hwnd, hdc);
  63.  
  64.     return hfont;
  65. }
  66.  
  67.  
  68.  
  69. /**************************************************************************
  70.  * InitViewerInfo
  71.  *
  72.  * Initializes all the Viewer instance information needed by the search
  73.  * DLL.
  74.  *
  75.  * Returns zero if successful or an error code if unsuccessful.
  76.  **************************************************************************/
  77.  
  78. int InitViewerInfo(
  79.     LPVWRINFO lpVwrInfo,            // Block of Viewer instance data
  80.     HWND hwndViewer,                // Viewer window handle
  81.     LPSTR lpszTitle)                // Title filename
  82. {
  83.     // Store MVB filename
  84.  
  85.     if(lpVwrInfo->szMVB[0] == '\0')
  86.         lstrcpy(lpVwrInfo->szMVB, lpszTitle);
  87.  
  88.     // Register window message for identifying Results dialog
  89.     // to Viewer
  90.  
  91.     if(lpVwrInfo->uiWMRegDlg == NULL)
  92.         lpVwrInfo->uiWMRegDlg = RegisterWindowMessage("MS_VWRSRCHRESDLG");
  93.  
  94.     // Record Viewer handle
  95.  
  96.     if(lpVwrInfo->vwr == NULL)
  97.     {
  98.         lpVwrInfo->hwndViewer = hwndViewer;
  99.         lpVwrInfo->vwr        = VwrFromHwnd(hwndViewer);
  100.  
  101.         if(lpVwrInfo->vwr == NULL)
  102.             return KSERR_NOVWR;
  103.     }
  104.  
  105.     // Get a title handle
  106.  
  107.     if(lpVwrInfo->htitle == NULL)
  108.     {
  109.         lpVwrInfo->htitle = TitleOpen(lpszTitle);
  110.         if(lpVwrInfo->htitle == NULL)
  111.             return KSERR_CANTOPENTITLE;
  112.     }
  113.  
  114.     // Get our dialog-box font
  115.  
  116.     if(lpVwrInfo->hfontDlg == NULL)
  117.         lpVwrInfo->hfontDlg = GetDialogFont(hwndViewer);
  118.  
  119.     return 0;
  120. }
  121.  
  122.  
  123.  
  124. /**************************************************************************
  125.  * DoSearchDialog
  126.  *
  127.  * Entry-point function for search interface. This function retrieves and
  128.  * stores information needed during the search, displays the
  129.  * search dialog box, and then displays the Results dialog box if the
  130.  * search was performed.
  131.  *
  132.  * Register with: RegisterRoutine("katasrch","DoSearchDialog","US")
  133.  * Call with:     DoSearchDialog(hwndApp,qchPath)
  134.  *
  135.  **************************************************************************/
  136.  
  137. void WINAPI DoSearchDialog(
  138.     DWORD dwHwndViewer,         // LOWORD has the Viewer window handle
  139.     LPSTR lpszTitle)            // Title filename
  140. {
  141.     LPVWRINFO lpVwrInfo;
  142.     HWND      hwndViewer = LOWORD(dwHwndViewer);
  143.     int       iRet;
  144.     RECT      rc;
  145.  
  146.     // Get the task data
  147.  
  148.     lpVwrInfo = GetTaskData(GetCurrentTask());
  149.     if(lpVwrInfo == NULL)
  150.     {
  151.         ShowMessage(hwndViewer, KSERR_NOVWRINFO, MB_ICONEXCLAMATION);
  152.         return;
  153.     }
  154.  
  155.     // Initialize the task-information structure
  156.  
  157.     iRet = InitViewerInfo(lpVwrInfo, hwndViewer, lpszTitle);
  158.     if(iRet)
  159.     {
  160.         ShowMessage(hwndViewer, iRet, MB_ICONEXCLAMATION);
  161.         return;
  162.     }
  163.  
  164.     // Display the Search dialog box
  165.  
  166.     iRet = DialogBoxParam(ghModule, MAKEINTRESOURCE(ID_SEARCHDIALOG), 
  167.                 hwndViewer, SearchDlgProc, (LPARAM)lpVwrInfo);
  168.  
  169.     if(iRet)
  170.     {
  171.         GetWindowRect(lpVwrInfo->hwndViewer, &rc);
  172.  
  173.         lpVwrInfo->hwndResults = CreateDialog(ghModule,
  174.                                     MAKEINTRESOURCE(ID_RESULTSDIALOG),
  175.                                     lpVwrInfo->hwndViewer,
  176.                                     ResultsDlgProc);
  177.  
  178.         if(lpVwrInfo->hwndResults == NULL)
  179.         {
  180.             TopicListDestroy(lpVwrInfo->htlResults);
  181.             HighlightDestroy(lpVwrInfo->hHighlight);
  182.  
  183.             lpVwrInfo->htlResults = NULL;
  184.             lpVwrInfo->hHighlight = NULL;
  185.  
  186.             ShowMessage(hwndViewer, KSERR_CANTCREATERESULTS, 
  187.                     MB_ICONEXCLAMATION);
  188.         }
  189.     }
  190. }
  191.  
  192.  
  193.  
  194.  
  195. /**************************************************************************
  196.  * ExecFullTextSearch
  197.  *
  198.  * Entry-point function for QuicKeys search interface. This function
  199.  * performs a search using the supplied query and displays a results
  200.  * dialog box.
  201.  *
  202.  * Register with: RegisterRoutine("katasrch","ExecFullTextSearch","USSS")
  203.  * Call with:     ExecFullTextSearch(hwndApp, qchPath, "query text", "")
  204.  *
  205.  **************************************************************************/
  206.  
  207. void WINAPI ExecFullTextSearch(
  208.     DWORD dwHwndViewer,         // LOWORD has the Viewer window handle
  209.     LPSTR lpszTitle,            // Title filename
  210.     LPSTR lpszQuery,            // Query text
  211.     LPSTR lpszUnused)           // Unused (left for 1.0 compatibility)
  212. {
  213.     LPVWRINFO  lpVwrInfo;
  214.     HWND       hwndViewer = LOWORD(dwHwndViewer);
  215.     QUERYERR   qerr;
  216.     int        iRet;
  217.     RECT       rc;
  218.  
  219.     // Get the task data
  220.  
  221.     lpVwrInfo = GetTaskData(GetCurrentTask());
  222.     if(lpVwrInfo == NULL)
  223.     {
  224.         ShowMessage(hwndViewer, KSERR_NOVWRINFO, MB_ICONEXCLAMATION);
  225.  
  226.         return;
  227.     }
  228.  
  229.     // Initialize the task-information structure
  230.  
  231.     iRet = InitViewerInfo(lpVwrInfo, hwndViewer, lpszTitle);
  232.     if(iRet)
  233.     {
  234.         ShowMessage(hwndViewer, iRet, MB_ICONEXCLAMATION);
  235.         return;
  236.     }
  237.  
  238.     iRet = DoSearch(lpVwrInfo, lpszQuery, NULL, &qerr, 
  239.                 IMPLICIT_OR | TL_QKEY);
  240.     if(iRet)
  241.     {
  242.         ShowMessage(hwndViewer, iRet, MB_ICONEXCLAMATION);
  243.         return;
  244.     }
  245.  
  246.     GetWindowRect(lpVwrInfo->hwndViewer, &rc);
  247.  
  248.     lpVwrInfo->hwndResults = CreateDialog(ghModule,
  249.                                 MAKEINTRESOURCE(ID_RESULTSDIALOG),
  250.                                 lpVwrInfo->hwndViewer,
  251.                                 ResultsDlgProc);
  252.  
  253.     if(lpVwrInfo->hwndResults == NULL)
  254.     {
  255.         TopicListDestroy(lpVwrInfo->htlResults);
  256.         HighlightDestroy(lpVwrInfo->hHighlight);
  257.  
  258.         lpVwrInfo->htlResults = NULL;
  259.         lpVwrInfo->hHighlight = NULL;
  260.  
  261.         ShowMessage(hwndViewer, KSERR_CANTCREATERESULTS, MB_ICONEXCLAMATION);
  262.     }
  263. }
  264.  
  265.  
  266.  
  267. /***************************************************************************
  268.  * LDLLHandler
  269.  *
  270.  * Provides the message interface between the DLL and the title.
  271.  *
  272.  ***************************************************************************/
  273.  
  274.  
  275. LONG WINAPI LDLLHandler(
  276.     UINT msg,                           // Message to process
  277.     LPARAM lParam1,                     // Message-dependent information
  278.     LPARAM lParam2)                     // Message-dependent information
  279. {
  280.     LPVWRINFO lpVwrInfo;
  281.  
  282.     switch(msg)
  283.     {
  284.     case DW_WHATMSG:
  285.         return DC_INITTERM | DC_JUMP | DC_CONFIG;
  286.  
  287.     case DW_INIT:
  288.         // Get the current task handle. Allocate a block of instance
  289.         // data and store in a table indexed by this task handle.
  290.  
  291.         lpVwrInfo = AddTask(GetCurrentTask());
  292.  
  293.         // A FALSE return value cancels the loading of the DLL.
  294.  
  295.         return lpVwrInfo != NULL;
  296.  
  297.     case DW_CHGFILE:
  298.         // Ignore this message if this is a secondary window jump
  299.  
  300.         if(lParam2)
  301.             return TRUE;
  302.  
  303.         // Get the current task handle and retrieve the instance data
  304.         // for this task.
  305.  
  306.         lpVwrInfo = GetTaskData(GetCurrentTask());
  307.         if(lpVwrInfo == NULL)
  308.         {
  309.             ShowMessage(NULL, KSERR_NOVWRINFO, MB_ICONEXCLAMATION);
  310.             return TRUE;
  311.         }
  312.  
  313.         // Close the results window, if it's displayed. Results window will
  314.         // clean up the topic list and highlight information.
  315.  
  316.         if(lpVwrInfo->hwndResults)
  317.         {
  318.             DestroyWindow(lpVwrInfo->hwndResults);
  319.             lpVwrInfo->hwndResults = NULL;
  320.         }
  321.  
  322.         if(lpVwrInfo->htitle)
  323.         {
  324.             TitleClose(lpVwrInfo->htitle);
  325.             lpVwrInfo->htitle = NULL;
  326.         }
  327.  
  328.         lstrcpy(lpVwrInfo->szMVB, (LPSTR)lParam1);
  329.  
  330.         return TRUE;
  331.  
  332.     case DW_TERM:
  333.         // Get the current task handle and retrieve the instance data
  334.         // for this task.
  335.  
  336.         lpVwrInfo = GetTaskData(GetCurrentTask());
  337.         if(lpVwrInfo == NULL)
  338.         {
  339.             ShowMessage(NULL, KSERR_NOVWRINFO, MB_ICONEXCLAMATION);
  340.             return TRUE;
  341.         }
  342.  
  343.         // If the DLL has an open title associated with this instance,
  344.         // close the title.
  345.  
  346.         if(lpVwrInfo->htitle)
  347.             TitleClose(lpVwrInfo->htitle);
  348.  
  349.         if(lpVwrInfo->hfontDlg)
  350.             DeleteObject(lpVwrInfo->hfontDlg);
  351.  
  352.         if(lpVwrInfo->vwrHelp)
  353.             VwrQuit(lpVwrInfo->vwrHelp);
  354.  
  355.         DeleteTask(GetCurrentTask());
  356.  
  357.         return TRUE;
  358.  
  359.     case DW_STARTJUMP:
  360.     case DW_ENDJUMP:
  361.         return TRUE;
  362.     }
  363. }
  364.  
  365. /*************************************************************************
  366.  * DoSearch
  367.  *
  368.  * Workhorse function that submits the specified query. This function
  369.  * also destroys an existing Results dialog box prior to recording the
  370.  * new topic list and highlight data.
  371.  *
  372.  * Returns zero if successful; otherwise, returns an error code.
  373.  *************************************************************************/
  374.  
  375. int DoSearch(
  376.     LPVWRINFO  lpVwrInfo,
  377.     LPSTR      lpszQuery,
  378.     HTLIST     htlDomain,
  379.     LPQUERYERR lpqerr,
  380.     WORD       wFlags)
  381. {
  382.     HCURSOR hcurOld;
  383.     HTLIST  htl;
  384.     HANDLE  hHL;
  385.  
  386.     hcurOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
  387.  
  388.     // Submit the query
  389.  
  390.     htl = TopicListFromQuery(lpVwrInfo->htitle, wFlags, lpszQuery,
  391.                              htlDomain, NULL, NULL, 
  392.                              &hHL, lpqerr);
  393.  
  394.     if(hcurOld)
  395.         SetCursor(hcurOld);
  396.  
  397.     if(htl == NULL)
  398.         return KSERR_QUERY;
  399.  
  400.     lpVwrInfo->lNumTopics = TopicListLength(htl);
  401.     if(lpVwrInfo->lNumTopics <= 0)
  402.     {
  403.         TopicListDestroy(htl);
  404.         HighlightDestroy(hHL);
  405.  
  406.         return KSERR_NOTOPICSFOUND;
  407.     }
  408.  
  409.     if(lpVwrInfo->hwndResults)
  410.     {
  411.         DestroyWindow(lpVwrInfo->hwndResults);
  412.     }
  413.  
  414.     lpVwrInfo->htlResults = htl;
  415.     lpVwrInfo->hHighlight = hHL;
  416.  
  417.     return 0;
  418. }
  419.  
  420. /************************************************************************
  421.  * ShowMessage: Load a string resource and display in a message box.
  422.  *
  423.  ************************************************************************/
  424.  
  425. void ShowMessage(HWND hWnd, int nMessage, int nIcon)
  426. {
  427.     char szMessage[512];
  428.  
  429.     MessageBeep(nIcon);
  430.  
  431.     if(LoadString(ghModule, nMessage, szMessage, 511) > 0)
  432.     {
  433.         MessageBox(hWnd, szMessage, szTitleSearch, 
  434.                     MB_OK | nIcon);
  435.     }
  436.     else
  437.     {
  438.         MessageBox(hWnd, "Unspecified error.", szTitleSearch, 
  439.                     MB_OK | nIcon);
  440.     }
  441. }
  442.  
  443. /************************************************************************
  444.  * ShowQueryError: Displays Viewer query error message and positions
  445.  *                 combo-box cursor at position of error.
  446.  *
  447.  ************************************************************************/
  448.  
  449. void ShowQueryError(HWND hWnd, LPQUERYERR lpqerr)
  450. {
  451.     static char*szGenericMsg = "Error in search text at specified position.";
  452.  
  453.     char szResStr[256];
  454.     int  nRes;
  455.  
  456.     switch(lpqerr->iError)
  457.     {
  458.     case ERR_NULLQUERY:     
  459.     case ERR_EXPECTEDTERM:  
  460.     case ERR_MISSQUOTE:     
  461.     case ERR_MISSLPAREN:    
  462.     case ERR_MISSRPAREN:    
  463.     case ERR_TOODEEP:       
  464.     case ERR_TOOMANYTOKENS: 
  465.     case ERR_BADVALUE:      
  466.     case ERR_BADRANGEOP:    
  467.     case ERR_ALL_WILD:      
  468.     case ERR_NON_LAST_WILD:
  469.         nRes = KSERR_QUERYBASE + lpqerr->iError;
  470.         if(LoadString(ghModule, nRes, szResStr, 255))
  471.             break;
  472.  
  473.         // If LoadString failed for our custom messages, fall through and
  474.         // try to load the Viewer message.
  475.  
  476.     default:
  477.         if(QueryGetErrorMessage(lpqerr->iError, szResStr, 255) == 0)
  478.         {
  479.             lstrcpy(szResStr, szGenericMsg);
  480.         }
  481.         break;
  482.     }
  483.  
  484.     MessageBeep(MB_ICONEXCLAMATION);
  485.     MessageBox(hWnd, szResStr, szTitleSearch, 
  486.                 MB_OK | MB_ICONEXCLAMATION);
  487.  
  488.     SetFocus(hWnd);
  489.     SendMessage(hWnd, EM_SETSEL, 1, MAKELONG(lpqerr->iStart, lpqerr->iStart));
  490. }
  491.  
  492.  
  493. /**********************************************************************
  494.  * DisplaySearchHelp
  495.  *
  496.  * Submits a jump command to display search help in a secondary
  497.  * window. To display a secondary window that doesn't interfere with
  498.  * the functioning of the Search dialog box, we use a second, hidden
  499.  * Viewer instance. This means the secondary window is independent of
  500.  * the Viewer instance displaying the karate topics. Each instance of
  501.  * the karate title uses its own hidden Viewer instance to display
  502.  * Help.
  503.  *
  504.  * Note: When this function is first called for a given Viewer session,
  505.  * it starts the hidden Viewer instance and stores the VWR identifier
  506.  * in the variable referenced by lpvwrHelp.
  507.  *
  508.  **********************************************************************/
  509.  
  510. int DisplaySearchHelp(
  511.     VWR FAR *lpvwrHelp,         // Pointer to a VWR identifier
  512.     LPSTR lpszMVB)              // Name of help file
  513. {
  514.     char szCommand[64];
  515.  
  516.     if(LoadString(ghModule, ID_HELPCOMMAND, szCommand, 63) == 0)
  517.         return KSERR_MEMORY;
  518.  
  519.     if(*lpvwrHelp == NULL)
  520.     {
  521.         *lpvwrHelp = VwrCommand(NULL, lpszMVB, szCommand, cmdoptHIDE);
  522.         if(*lpvwrHelp)
  523.             return 0;
  524.         else
  525.             return KSERR_NOVWR;
  526.     }
  527.     else
  528.     {
  529.         if(VwrCommand(*lpvwrHelp, NULL, szCommand, cmdoptNONE) == *lpvwrHelp)
  530.             return 0;
  531.         else
  532.             return KSERR_NOVWR;
  533.     }
  534. }
  535.  
  536.  
  537. /**********************************************************************
  538.  * LoadWheel
  539.  *
  540.  * Loads the phrases of a word wheel into a combo box.
  541.  *
  542.  **********************************************************************/
  543.  
  544. int LoadWheel(
  545.     HWND  hwndCB,               // Window handle of combo box
  546.     LPSTR lpszMVB,              // Filename of title file
  547.     LPSTR lpszWheel)            // Word wheel name
  548. {
  549.     int    i;                   // Index into word wheel
  550.     LONG   lLen;                // Length of word wheel
  551.     HWHEEL hWheel;              // Handle to word wheel
  552.     char   szPhrase[129];       // Buffer to hold word-wheel phrase
  553.     int    iRet = 0;            // Assume success
  554.  
  555.     // Try to open the specified word wheel
  556.  
  557.     hWheel = WordWheelOpen(lpszMVB, lpszWheel);
  558.     if(hWheel == NULL)
  559.     {
  560.         return KSERR_CANTOPENWORDWHEEL;
  561.     }
  562.  
  563.     // Retrieve each phrase and add it to the combo box
  564.  
  565.     for(i = 0, lLen = WordWheelLength(hWheel); i < lLen; i++)
  566.     {
  567.         if(WordWheelLookup(hWheel, i, szPhrase, 128))
  568.         {
  569.             iRet = KSERR_CANTLOADWORDWHEELPHRASE;
  570.             break;
  571.         }
  572.         SendMessage(hwndCB, CB_ADDSTRING, 0, (LPARAM)(LPSTR)szPhrase);
  573.     }
  574.  
  575.     // Close the word wheel
  576.  
  577.     WordWheelClose(hWheel);
  578.  
  579.     return iRet;
  580. }
  581.  
  582.  
  583.  
  584. /**********************************************************************
  585.  * LoadGroup
  586.  *
  587.  * Creates a merged topic list consisting of the topics in the
  588.  * list specified in htlDomain and the topics in the topic group
  589.  * specified by lpszGroup.
  590.  *
  591.  **********************************************************************/
  592.  
  593. HTLIST LoadGroup(
  594.     HTITLE hTitle,      // Title containing topic group
  595.     HTLIST htlDomain,   // Domain list to merge with group
  596.     LPSTR  lpszGroup,   // Name of group to load
  597.     int    nOp,         // Merge operation
  598.     BOOL   bDelete)     // Delete original domain list?
  599. {
  600.     HTLIST htlGrp;              // To receive loaded group
  601.     HTLIST htlMerge;            // To receive merged group
  602.  
  603.     // Load topic group. If load fails, return error.
  604.  
  605.     htlGrp = TopicListLoad(hTitle, lpszGroup);
  606.     if(htlGrp == NULL)
  607.     {
  608.         return NULL;
  609.     }
  610.  
  611.     // Don't need to merge if domain list is NULL
  612.  
  613.     if(htlDomain == NULL)
  614.     {
  615.         return htlGrp;
  616.     }
  617.  
  618.     // Merge domain list with group
  619.  
  620.     htlMerge = TopicListCombine(nOp, htlDomain, htlGrp, FALSE);
  621.  
  622.     // Delete component groups
  623.  
  624.     if(bDelete)
  625.         TopicListDestroy(htlDomain);
  626.  
  627.     TopicListDestroy(htlGrp);
  628.  
  629.     // Return merged list (NULL if TopicListCombine failed)
  630.  
  631.     return htlMerge;
  632. }
  633.  
  634.  
  635.  
  636. /**********************************************************************
  637.  * BuildDomain
  638.  *
  639.  * Creates a topic list containing all the groups indicated in the
  640.  * dialog box fields.
  641.  *
  642.  **********************************************************************/
  643.  
  644. int BuildDomain(
  645.     HWND   hwnd,            // Handle to query dialog
  646.     LPVWRINFO lpVwrInfo,    // Viewer instance information
  647.     HTLIST FAR *lphtl)      // Where to store the domain list
  648. {
  649.     char   szGroup[20];
  650.     HTLIST htlRet;
  651.     int    i, iRet;
  652.  
  653.     *lphtl = NULL;
  654.  
  655.     if(!IsDlgButtonChecked(hwnd, ID_GROUPSEL))
  656.         return 0;
  657.  
  658.     for(i = ID_CUONGNHU; i <= ID_WINGTSUN; i++)
  659.     {
  660.         if(SendDlgItemMessage(hwnd, i, BM_GETCHECK, 0, 0L))
  661.         {
  662.             if(LoadString(ghModule, i, szGroup, 19) == 0)
  663.             {
  664.                 iRet = KSERR_MEMORY;
  665.                 goto ErrorCleanup;
  666.             }
  667.  
  668.             htlRet = LoadGroup(lpVwrInfo->htitle, *lphtl, szGroup, 
  669.                                     TL_OR, FALSE);
  670.             if(htlRet == NULL)
  671.             {
  672.                 iRet = KSERR_CANTOPENTOPICGROUP;
  673.                 goto ErrorCleanup;
  674.             }
  675.             *lphtl = htlRet;
  676.         }
  677.     }
  678.  
  679.     if(*lphtl == NULL)
  680.         return KSERR_NOGROUPSSELECTED;
  681.     else
  682.         return 0;
  683.  
  684. ErrorCleanup:
  685.  
  686.     if(*lphtl)
  687.         TopicListDestroy(*lphtl);
  688.  
  689.     return iRet;
  690. }
  691.  
  692.  
  693. /**********************************************************************
  694.  * BuildQuery
  695.  *
  696.  * Builds a query string using the information entered in the search
  697.  * dialog box fields.
  698.  *
  699.  **********************************************************************/
  700.  
  701. int BuildQuery(
  702.     HWND      hwnd,         // Handle to query dialog
  703.     LPVWRINFO lpVwrInfo,    // Viewer instance information
  704.     LPSTR     lpszQuery)    // Where to store the query text
  705. {
  706.     char    szLevel[QUERY_LENGTH+1];
  707.     char    szText[QUERY_LENGTH+1];
  708.  
  709.     int     iQueryLen, iLevelLen;
  710.  
  711.     // Check to see if a query was entered.
  712.  
  713.     iQueryLen = GetWindowTextLength(GetDlgItem(hwnd, ID_QUERY));
  714.     iLevelLen = GetWindowTextLength(GetDlgItem(hwnd, ID_RANK));
  715.  
  716.     // The user can enter a query, a level (rank), or both.
  717.  
  718.     if((iQueryLen == 0) && (iLevelLen == 0))
  719.         return KSERR_NOQUERY;
  720.  
  721.     if((iQueryLen > QUERY_LENGTH) || (iLevelLen == QUERY_LENGTH))
  722.         return KSERR_QUERYLENGTH;
  723.  
  724.     // Build the query
  725.  
  726.     GetDlgItemText(hwnd, ID_RANK,  szLevel, QUERY_LENGTH);
  727.     GetDlgItemText(hwnd, ID_QUERY,  szText,  QUERY_LENGTH);
  728.  
  729.     if(*szLevel)
  730.         wsprintf(lpszQuery, "%s VFLD %d %s VFLD 0", 
  731.                             (LPSTR)szText, WHEEL_LEVEL, (LPSTR)szLevel);
  732.     else
  733.         lstrcpy(lpszQuery, szText);
  734.  
  735. OutputDebugString(lpszQuery); OutputDebugString("\r\n");
  736.  
  737.     return 0;
  738. }
  739.  
  740.  
  741. /**************************************************************************
  742.  * DoQueryDialogSearch
  743.  *
  744.  * Performs a search from the query dialog box. Collects necessary
  745.  * information from the query dialog and then calls DoSearch to submit
  746.  * the query and display the results window.
  747.  **************************************************************************/
  748.  
  749. int DoQueryDialogSearch(
  750.     HWND hwnd,              // Window handle of query dialog
  751.     LPVWRINFO lpVwrInfo,    // Viewer task info 
  752.     LPQUERYERR lpqerr)      // Pointer to query error structure
  753. {
  754.     char   szQuery[QUERY_LENGTH*2+1];
  755.     HTLIST htlDomain;
  756.     int iRet;
  757.  
  758.     iRet = BuildQuery(hwnd, lpVwrInfo, szQuery);
  759.     if(iRet)
  760.         return iRet;
  761.  
  762.     iRet = BuildDomain(hwnd, lpVwrInfo, &htlDomain);
  763.     if(iRet)
  764.         return iRet;
  765.  
  766.     iRet = DoSearch(lpVwrInfo, szQuery, htlDomain, lpqerr, IMPLICIT_AND);
  767.  
  768.     if(htlDomain)
  769.         TopicListDestroy(htlDomain);
  770.  
  771.     return iRet;
  772. }
  773.  
  774.  
  775.  
  776. /**************************************************************************
  777.  * InitDialogControls
  778.  *
  779.  * Loads word-wheel info for the Rank combo box, sets various check boxes,
  780.  * changes fonts for controls.
  781.  **************************************************************************/
  782.  
  783. int InitDialogControls(
  784.     HWND hwnd,              // Window handle of query dialog
  785.     LPVWRINFO lpVwrInfo)    // Viewer task info
  786. {
  787.     int iRet, i;
  788.  
  789.     iRet = LoadWheel(GetDlgItem(hwnd, ID_RANK), lpVwrInfo->szMVB, "level");
  790.     if(iRet)
  791.         return iRet;
  792.  
  793.     SendDlgItemMessage(hwnd, ID_SHOTOKAN, BM_SETCHECK, 1, 0L);
  794.     SendDlgItemMessage(hwnd, ID_CUONGNHU, BM_SETCHECK, 1, 0L);
  795.     SendDlgItemMessage(hwnd, ID_WINGTSUN, BM_SETCHECK, 1, 0L);
  796.  
  797.     CheckRadioButton(hwnd, ID_GROUPANY, ID_GROUPSEL, ID_GROUPANY);
  798.  
  799.     SendMessage(hwnd, WM_COMMAND, ID_GROUPANY, 
  800.                 MAKELONG(GetDlgItem(hwnd, ID_GROUPANY), BN_CLICKED));
  801.  
  802.     if(lpVwrInfo->hfontDlg)
  803.     {
  804.         for(i = ID_TEXT1; i <= ID_WINGTSUN; i++)
  805.             SendDlgItemMessage(hwnd, i, WM_SETFONT, 
  806.                                 (WPARAM)lpVwrInfo->hfontDlg, TRUE);
  807.         SendDlgItemMessage(hwnd, IDOK, WM_SETFONT, 
  808.                             (WPARAM)lpVwrInfo->hfontDlg, TRUE);
  809.         SendDlgItemMessage(hwnd, IDCANCEL, WM_SETFONT, 
  810.                             (WPARAM)lpVwrInfo->hfontDlg, TRUE);
  811.         SendDlgItemMessage(hwnd, ID_HELP, WM_SETFONT, 
  812.                             (WPARAM)lpVwrInfo->hfontDlg, TRUE);
  813.     }
  814.  
  815.     return 0;
  816. }
  817.  
  818.  
  819. /**************************************************************************
  820.  * SearchDlgProc
  821.  *
  822.  * Dialog-box procedure for search dialog box.
  823.  **************************************************************************/
  824.  
  825. BOOL CALLBACK SearchDlgProc(
  826.     HWND hwnd,              // Window handle
  827.     UINT msg,               // Message
  828.     WPARAM wParam,          // Message parameter
  829.     LPARAM lParam)          // Message parameter
  830. {
  831.     LPVWRINFO lpVwrInfo;
  832.     QUERYERR  qerr;
  833.     int       iRet;
  834.  
  835.     switch(msg) 
  836.     {
  837.     case WM_INITDIALOG:
  838.         // Get the Viewer instance data passed to lParam
  839.  
  840.         lpVwrInfo = (LPVWRINFO)lParam;
  841.         if(lpVwrInfo == NULL)
  842.         {
  843.             ShowMessage(hwnd, KSERR_NOVWRINFO, MB_ICONEXCLAMATION);
  844.             EndDialog(hwnd, 0);
  845.             return TRUE;
  846.         }
  847.  
  848.         // Initialize the dialog-box controls
  849.  
  850.         iRet = InitDialogControls(hwnd, lpVwrInfo);
  851.         if(iRet)
  852.         {
  853.             EndDialog(hwnd, 0);
  854.         }
  855.  
  856.         return TRUE;
  857.  
  858.     case WM_COMMAND:
  859.         switch(wParam)
  860.         {
  861.         case IDOK:
  862.  
  863.             // Get Viewer instance data for current task
  864.  
  865.             lpVwrInfo = GetTaskData(GetCurrentTask());
  866.             if(lpVwrInfo == NULL)
  867.             {
  868.                 ShowMessage(hwnd, KSERR_NOVWRINFO, MB_ICONEXCLAMATION);
  869.                 break;
  870.             }
  871.  
  872.             // Perform the search
  873.  
  874.             iRet = DoQueryDialogSearch(hwnd, lpVwrInfo, &qerr);
  875.             switch(iRet)
  876.             {
  877.             case 0:
  878.                 EndDialog(hwnd, 1);
  879.                 
  880.                 break;
  881.  
  882.             case KSERR_QUERY:
  883.  
  884.                 ShowQueryError(GetDlgItem(hwnd, ID_QUERY), &qerr);
  885.                 break;
  886.  
  887.             default:
  888.                 ShowMessage(hwnd, iRet, MB_ICONEXCLAMATION);
  889.                 break;
  890.             }
  891.             break;
  892.  
  893.         case IDCANCEL:
  894.             EndDialog(hwnd, 0);
  895.  
  896.             break;
  897.  
  898.         case ID_HELP:
  899.             // Get Viewer instance data for current task
  900.  
  901.             lpVwrInfo = GetTaskData(GetCurrentTask());
  902.             if(lpVwrInfo == NULL)
  903.             {
  904.                 ShowMessage(hwnd, KSERR_NOVWRINFO, MB_ICONEXCLAMATION);
  905.                 EndDialog(hwnd, 0);
  906.  
  907.                 break;
  908.             }
  909.  
  910.             // Display the help window for search
  911.  
  912.             iRet = DisplaySearchHelp(&lpVwrInfo->vwrHelp, lpVwrInfo->szMVB);
  913.             if(iRet)
  914.                 ShowMessage(hwnd, iRet, MB_ICONEXCLAMATION);
  915.  
  916.             break;
  917.            
  918.  
  919.         case ID_GROUPANY:
  920.         case ID_GROUPSEL:
  921.             if(HIWORD(lParam) != BN_CLICKED)
  922.                 break;
  923.  
  924.             EnableWindow(GetDlgItem(hwnd, ID_SHOTOKAN), wParam == ID_GROUPSEL);
  925.             EnableWindow(GetDlgItem(hwnd, ID_CUONGNHU), wParam == ID_GROUPSEL);
  926.             EnableWindow(GetDlgItem(hwnd, ID_WINGTSUN), wParam == ID_GROUPSEL);
  927.  
  928.             break;
  929.         }
  930.         break;
  931.  
  932.     case WM_CLOSE:
  933.         EndDialog(hwnd,0);
  934.         break;
  935.     }
  936.     return FALSE;
  937. }
  938.  
  939.  
  940.